/***************************************************************************//**
 * @file
 * @brief Silicon Labs PSA Crypto Transparent Driver functions for SE.
 *******************************************************************************
 * # License
 * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
 *******************************************************************************
 *
 * SPDX-License-Identifier: Zlib
 *
 * The licensor of this software is Silicon Laboratories Inc.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 ******************************************************************************/
#ifndef SLI_SE_TRANSPARENT_FUNCTIONS_H
#define SLI_SE_TRANSPARENT_FUNCTIONS_H

/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN

/***************************************************************************//**
 * \addtogroup sl_psa_drivers
 * \{
 ******************************************************************************/

/***************************************************************************//**
 * \addtogroup sl_psa_drivers_se CRYPTOACC transparent PSA driver
 * \brief Driver plugin for Silicon Labs SE peripheral adhering to the PSA
 *        transparent accelerator specification.
 * \{
 ******************************************************************************/

#include "sli_psa_driver_features.h"

#if defined(SLI_MBEDTLS_DEVICE_HSE)

#include "sli_se_transparent_types.h"

// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"

/* NOTE: This header file will be autogenerated by PSA Crypto build system based
 * on the definitions in sli_se_transparent_driver.json. However, until such a
 * system is in place, we rely on manually writing the file */

#ifdef __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------
// General

psa_status_t sli_se_transparent_driver_init(void);

psa_status_t sli_se_transparent_driver_deinit(void);

//------------------------------------------------------------------------------
// Hashing

psa_status_t sli_se_transparent_hash_setup(
  sli_se_transparent_hash_operation_t *operation,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_hash_update(
  sli_se_transparent_hash_operation_t *operation,
  const uint8_t *input,
  size_t input_length);

psa_status_t sli_se_transparent_hash_finish(
  sli_se_transparent_hash_operation_t *operation,
  uint8_t *hash,
  size_t hash_size,
  size_t *hash_length);

psa_status_t sli_se_transparent_hash_abort(
  sli_se_transparent_hash_operation_t *operation);

psa_status_t sli_se_transparent_hash_compute(psa_algorithm_t alg,
                                             const uint8_t *input,
                                             size_t input_length,
                                             uint8_t *hash,
                                             size_t hash_size,
                                             size_t *hash_length);

psa_status_t sli_se_transparent_hash_clone(
  const sli_se_transparent_hash_operation_t *source_operation,
  sli_se_transparent_hash_operation_t *target_operation);

//------------------------------------------------------------------------------
// Cipher

psa_status_t sli_se_transparent_cipher_encrypt(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *iv,
  size_t iv_length,
  const uint8_t *input,
  size_t input_length,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

psa_status_t sli_se_transparent_cipher_decrypt(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *input,
  size_t input_length,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

psa_status_t sli_se_transparent_cipher_encrypt_setup(
  sli_se_transparent_cipher_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_cipher_decrypt_setup(
  sli_se_transparent_cipher_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_cipher_set_iv(
  sli_se_transparent_cipher_operation_t *operation,
  const uint8_t *iv,
  size_t iv_length);

psa_status_t sli_se_transparent_cipher_update(
  sli_se_transparent_cipher_operation_t *operation,
  const uint8_t *input,
  size_t input_length,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

psa_status_t sli_se_transparent_cipher_abort(
  sli_se_transparent_cipher_operation_t *operation);

psa_status_t sli_se_transparent_cipher_finish(
  sli_se_transparent_cipher_operation_t *operation,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

//------------------------------------------------------------------------------
// Signature

psa_status_t sli_se_transparent_sign_message(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *input,
  size_t input_length,
  uint8_t *signature,
  size_t signature_size,
  size_t *signature_length);

psa_status_t sli_se_transparent_verify_message(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *input,
  size_t input_length,
  const uint8_t *signature,
  size_t signature_length);

psa_status_t sli_se_transparent_sign_hash(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *hash,
  size_t hash_length,
  uint8_t *signature,
  size_t signature_size,
  size_t *signature_length);

psa_status_t sli_se_transparent_verify_hash(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *hash,
  size_t hash_length,
  const uint8_t *signature,
  size_t signature_length);

//------------------------------------------------------------------------------
// MAC

psa_status_t sli_se_transparent_mac_compute(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *input,
  size_t input_length,
  uint8_t *mac,
  size_t mac_size,
  size_t *mac_length);

psa_status_t sli_se_transparent_mac_sign_setup(
  sli_se_transparent_mac_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_mac_verify_setup(
  sli_se_transparent_mac_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_mac_update(
  sli_se_transparent_mac_operation_t *operation,
  const uint8_t *input,
  size_t input_length);

psa_status_t sli_se_transparent_mac_sign_finish(
  sli_se_transparent_mac_operation_t *operation,
  uint8_t *mac,
  size_t mac_size,
  size_t *mac_length);

psa_status_t sli_se_transparent_mac_verify_finish(
  sli_se_transparent_mac_operation_t *operation,
  const uint8_t *mac,
  size_t mac_length);

psa_status_t sli_se_transparent_mac_abort(
  sli_se_transparent_mac_operation_t *operation);

//------------------------------------------------------------------------------
// AEAD

psa_status_t sli_se_transparent_aead_encrypt(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *nonce,
  size_t nonce_length,
  const uint8_t *additional_data,
  size_t additional_data_length,
  const uint8_t *plaintext,
  size_t plaintext_length,
  uint8_t *ciphertext,
  size_t ciphertext_size,
  size_t *ciphertext_length);

psa_status_t sli_se_transparent_aead_decrypt(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg,
  const uint8_t *nonce,
  size_t nonce_length,
  const uint8_t *additional_data,
  size_t additional_data_length,
  const uint8_t *ciphertext,
  size_t ciphertext_length,
  uint8_t *plaintext,
  size_t plaintext_size,
  size_t *plaintext_length);

psa_status_t sli_se_transparent_aead_encrypt_setup(
  sli_se_transparent_aead_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_aead_decrypt_setup(
  sli_se_transparent_aead_operation_t *operation,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  psa_algorithm_t alg);

psa_status_t sli_se_transparent_aead_set_nonce(
  sli_se_transparent_aead_operation_t *operation,
  const uint8_t *nonce,
  size_t nonce_length);

psa_status_t sli_se_transparent_aead_set_lengths(
  sli_se_transparent_aead_operation_t *operation,
  size_t ad_length,
  size_t plaintext_length);

psa_status_t sli_se_transparent_aead_update_ad(
  sli_se_transparent_aead_operation_t *operation,
  const uint8_t *input,
  size_t input_length);

psa_status_t sli_se_transparent_aead_update(
  sli_se_transparent_aead_operation_t *operation,
  const uint8_t *input,
  size_t input_length,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

psa_status_t sli_se_transparent_aead_finish(
  sli_se_transparent_aead_operation_t *operation,
  uint8_t *ciphertext,
  size_t ciphertext_size,
  size_t *ciphertext_length,
  uint8_t *tag,
  size_t tag_size,
  size_t *tag_length);

psa_status_t sli_se_transparent_aead_verify(
  sli_se_transparent_aead_operation_t *operation,
  uint8_t *plaintext,
  size_t plaintext_size,
  size_t *plaintext_length,
  const uint8_t *tag,
  size_t tag_length);

psa_status_t sli_se_transparent_aead_abort(
  sli_se_transparent_aead_operation_t *operation);

//------------------------------------------------------------------------------
// Key handling

psa_status_t sli_se_transparent_generate_key(
  const psa_key_attributes_t *attributes,
  uint8_t *key_buffer,
  size_t key_buffer_size,
  size_t *output_length);

psa_status_t sli_se_transparent_export_public_key(
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  uint8_t *data,
  size_t data_size,
  size_t *data_length);

psa_status_t sli_se_transparent_import_key(
  const psa_key_attributes_t *attributes,
  const uint8_t *data,
  size_t data_length,
  uint8_t *key_buffer,
  size_t key_buffer_size,
  size_t *key_buffer_length,
  size_t *bits);

//------------------------------------------------------------------------------
// Key agreement

psa_status_t sli_se_transparent_key_agreement(
  psa_algorithm_t alg,
  const psa_key_attributes_t *attributes,
  const uint8_t *key_buffer,
  size_t key_buffer_size,
  const uint8_t *peer_key,
  size_t peer_key_length,
  uint8_t *output,
  size_t output_size,
  size_t *output_length);

#ifdef __cplusplus
}
#endif

#endif // SLI_MBEDTLS_DEVICE_HSE

/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */

/// @endcond

#endif // SLI_SE_TRANSPARENT_FUNCTIONS_H
